home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / apply.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  53.8 KB  |  2,225 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)apply.c    3.1    93/06/24    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "edog.h"
  7.  
  8. #ifdef OVLB
  9.  
  10. static NEARDATA const char tools[] = { TOOL_CLASS, 0 };
  11.  
  12. static NEARDATA boolean did_dig_msg;
  13.  
  14. #ifdef TOURIST
  15. static int FDECL(use_camera, (struct obj *));
  16. #endif
  17. static int FDECL(use_towel, (struct obj *));
  18. static void FDECL(use_stethoscope, (struct obj *));
  19. static void FDECL(use_whistle, (struct obj *));
  20. static void FDECL(use_magic_whistle, (struct obj *));
  21. #ifdef WALKIES
  22. static void FDECL(use_leash, (struct obj *));
  23. #endif
  24. STATIC_DCL int NDECL(dig);
  25. #ifdef OVLB
  26. STATIC_DCL schar FDECL(fillholetyp, (int, int));
  27. #endif
  28. static boolean FDECL(wield_tool, (struct obj *));
  29. static int FDECL(use_pick_axe, (struct obj *));
  30. static int FDECL(use_mirror, (struct obj *));
  31. static void FDECL(use_bell, (struct obj *));
  32. static void FDECL(use_candelabrum, (struct obj *));
  33. static void FDECL(use_candle, (struct obj *));
  34. static void FDECL(use_lamp, (struct obj *));
  35. static void FDECL(use_tinning_kit, (struct obj *));
  36. static void FDECL(use_figurine, (struct obj *));
  37. static void FDECL(use_grease, (struct obj *));
  38. static boolean NDECL(rm_waslit);
  39. static void FDECL(mkcavepos, (XCHAR_P,XCHAR_P,int,BOOLEAN_P,BOOLEAN_P));
  40. static void FDECL(mkcavearea, (BOOLEAN_P));
  41. static void FDECL(digactualhole, (int));
  42.  
  43. #ifdef    AMIGA
  44. void FDECL( amii_speaker, ( struct obj *, char *, int ) );
  45. #endif
  46.  
  47. #ifdef TOURIST
  48. static int
  49. use_camera(obj)
  50.     struct obj *obj;
  51. {
  52.     register struct monst *mtmp;
  53.  
  54.     if(Underwater) {
  55.         pline("Using your camera underwater would void the warranty.");
  56.         return(0);
  57.     }
  58.     if(!getdir(NULL)) return(0);
  59.     if(u.uswallow) {
  60.         You("take a picture of %s's %s.", mon_nam(u.ustuck),
  61.             is_animal(u.ustuck->data) ? "stomach" : "interior");
  62.     } else if(obj->cursed && !rn2(2)) goto blindu;
  63.     else if(u.dz) {
  64.         You("take a picture of the %s.",
  65.             (u.dz > 0) ? surface(u.ux,u.uy) : "ceiling");
  66.     } else if(!u.dx && !u.dy) {
  67. blindu:
  68.         if(!Blind) {
  69.             You("are blinded by the flash!");
  70.             make_blinded((long)rnd(25),FALSE);
  71.         }
  72.     } else if ((mtmp = bhit(u.dx,u.dy,COLNO,FLASHED_LIGHT,
  73.                 (int(*)())0,(int(*)())0,obj)) != 0) {
  74.         if(mtmp->msleep) {
  75.             mtmp->msleep = 0;
  76.             if(cansee(mtmp->mx,mtmp->my))
  77.             pline("The flash awakens %s.", mon_nam(mtmp)); /* a3 */
  78.         } else if (mtmp->data->mlet != S_LIGHT)
  79.             if(mtmp->mcansee && haseyes(mtmp->data)) {
  80.             register int tmp = distu(mtmp->mx,mtmp->my);
  81.  
  82.             if(cansee(mtmp->mx,mtmp->my))
  83.                 pline("%s is blinded by the flash!", Monnam(mtmp));
  84.             if(mtmp->data == &mons[PM_GREMLIN]) {
  85.                 /* Rule #1: Keep them out of the light. */
  86.                 pline("%s cries out in pain!", Monnam(mtmp));
  87.                 if (mtmp->mhp > 1) mtmp->mhp--;
  88.             }
  89.             setmangry(mtmp);
  90.             if(tmp < 9 && !mtmp->isshk && rn2(4)) {
  91.                 mtmp->mflee = 1;
  92.                 if(rn2(4)) mtmp->mfleetim = rnd(100);
  93.             }
  94.             mtmp->mcansee = 0;
  95.             if(tmp < 3) {
  96.                 mtmp->mblinded = 0;
  97.             } else {
  98.                 mtmp->mblinded = rnd(1 + 50/tmp);
  99.             }
  100.             }
  101.     }
  102.     return 1;
  103. }
  104. #endif
  105.  
  106. static int
  107. use_towel(obj)
  108.     struct obj *obj;
  109. {
  110.     if(!freehand()) {
  111.         You("have no free %s!", body_part(HAND));
  112.         return 0;
  113.     } else if (obj->owornmask) {
  114.         You("cannot use it while you're wearing it!");
  115.         return 0;
  116.     } else if (obj->cursed) {
  117.         long old;
  118.         switch (rn2(3)) {
  119.         case 2:
  120.             old = Glib;
  121.             Glib += rn1(10, 3);
  122.             Your("%s %s!", makeplural(body_part(HAND)),
  123.             (old ? "are filthier than ever" : "get slimy"));
  124.             return 1;
  125.         case 1:
  126.             if (!Blindfolded) {
  127.             old = u.ucreamed;
  128.             u.ucreamed += rn1(10, 3);
  129.             pline("Yecch! Your %s %s gunk on it!", body_part(FACE),
  130.                   (old ? "has more" : "now has"));
  131.             make_blinded(Blinded + (long)u.ucreamed - old, TRUE);
  132.             } else {
  133.             if (ublindf->cursed) {
  134.                 You("push your blindfold %s.",
  135.                 rn2(2) ? "cock-eyed" : "crooked");
  136.             } else {
  137.                 You("push your blindfold off.");
  138.                 Blindf_off(ublindf);
  139.                 dropx(ublindf);
  140.             }
  141.             }
  142.             return 1;
  143.         case 0:
  144.             break;
  145.         }
  146.     }
  147.  
  148.     if (Glib) {
  149.         Glib = 0;
  150.         You("wipe off your %s.", makeplural(body_part(HAND)));
  151.         return 1;
  152.     } else if(u.ucreamed) {
  153.         Blinded -= u.ucreamed;
  154.         u.ucreamed = 0;
  155.  
  156.         if (!Blinded) {
  157.             pline("You've got the glop off.");
  158.             Blinded = 1;
  159.             make_blinded(0L,TRUE);
  160.         } else {
  161.             Your("%s feels clean now.", body_part(FACE));
  162.         }
  163.         return 1;
  164.     }
  165.  
  166.     Your("%s and %s are already clean.",
  167.         body_part(FACE), makeplural(body_part(HAND)));
  168.  
  169.     return 0;
  170. }
  171.  
  172. static char hollow_str[] = "hear a hollow sound.  This must be a secret %s!";
  173.  
  174. /* Strictly speaking it makes no sense for usage of a stethoscope to
  175.    not take any time; however, unless it did, the stethoscope would be
  176.    almost useless. */
  177. static void
  178. use_stethoscope(obj)
  179.     register struct obj *obj;
  180. {
  181.     register struct monst *mtmp;
  182.     register struct rm *lev;
  183.     register int rx, ry;
  184.  
  185.     if(!freehand()) {
  186.         You("have no free %s.", body_part(HAND));
  187.         return;
  188.     }
  189.     if (!getdir(NULL)) return;
  190.     if (u.uswallow && (u.dx || u.dy || u.dz)) {
  191.         mstatusline(u.ustuck);
  192.         return;
  193.     } else if (u.dz) {
  194.         if (Underwater)
  195.             You("hear faint splashing.");
  196.         else if (u.dz < 0 || Levitation)
  197.             You("can't reach the %s.",
  198.             (u.dz > 0) ? surface(u.ux,u.uy) : "ceiling");
  199.         else if (Is_stronghold(&u.uz))
  200.             You("hear the crackling of hellfire.");
  201.         else
  202.             pline("The %s seems healthy enough.", surface(u.ux,u.uy));
  203.         return;
  204.     } else if (obj->cursed && !rn2(2)) {
  205.         You("hear your heart beat.");
  206.         return;
  207.     }
  208.     if (Stunned || (Confusion && !rn2(5))) confdir();
  209.     if (!u.dx && !u.dy) {
  210.         ustatusline();
  211.         return;
  212.     }
  213.     rx = u.ux + u.dx; ry = u.uy + u.dy;
  214.     if (!isok(rx,ry)) {
  215.         You("hear a faint typing noise.");
  216.         return;
  217.     }
  218.     if ((mtmp = m_at(rx,ry)) != 0) {
  219.         mstatusline(mtmp);
  220.         if (mtmp->mundetected) {
  221.             mtmp->mundetected = 0;
  222.             if (cansee(rx,ry)) newsym(mtmp->my,mtmp->my);
  223.         }
  224.         return;
  225.     }
  226.     lev = &levl[rx][ry];
  227.     switch(lev->typ) {
  228.     case SDOOR:
  229.         You(hollow_str, "door");
  230.         lev->typ = DOOR;
  231.         newsym(rx,ry);
  232.         return;
  233.     case SCORR:
  234.         You(hollow_str, "passage");
  235.         lev->typ = CORR;
  236.         newsym(rx,ry);
  237.         return;
  238.     }
  239.     You("hear nothing special.");
  240. }
  241.  
  242. static char whistle_str[] = "produce a %s whistling sound.";
  243.  
  244. /*ARGSUSED*/
  245. static void
  246. use_whistle(obj)
  247. struct obj *obj;
  248. #if defined(applec)
  249. # pragma unused(obj)
  250. #endif
  251. {
  252.     You(whistle_str, "high");
  253.     wake_nearby();
  254. }
  255.  
  256. static void
  257. use_magic_whistle(obj)
  258. struct obj *obj;
  259. {
  260.     register struct monst *mtmp;
  261.  
  262.     if(obj->cursed && !rn2(2)) {
  263.         You("produce a high-pitched humming noise.");
  264.         wake_nearby();
  265.     } else {
  266.         makeknown(MAGIC_WHISTLE);
  267.         You(whistle_str, Hallucination ? "normal" : "strange");
  268.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  269.             if(mtmp->mtame) mnexto(mtmp);
  270.     }
  271. }
  272.  
  273. boolean
  274. um_dist(x,y,n)
  275. register xchar x, y, n;
  276. {
  277.     return((boolean)(abs(u.ux - x) > n  || abs(u.uy - y) > n));
  278. }
  279.  
  280. #endif /* OVLB */
  281.  
  282. #ifdef WALKIES
  283. #define MAXLEASHED    2
  284.  
  285. #ifdef OVLB
  286.  
  287. int
  288. number_leashed()
  289. {
  290.     register int i = 0;
  291.     register struct obj *obj;
  292.  
  293.     for(obj = invent; obj; obj = obj->nobj)
  294.         if(obj->otyp == LEASH && obj->leashmon != 0) i++;
  295.     return(i);
  296. }
  297.  
  298. void
  299. o_unleash(otmp)        /* otmp is about to be destroyed or stolen */
  300. register struct obj *otmp;
  301. {
  302.     register struct monst *mtmp;
  303.  
  304.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  305.         if(mtmp->m_id == (unsigned)otmp->leashmon)
  306.             mtmp->mleashed = 0;
  307.     otmp->leashmon = 0;
  308. }
  309.  
  310. void
  311. m_unleash(mtmp)        /* mtmp is about to die, or become untame */
  312. register struct monst *mtmp;
  313. {
  314.     register struct obj *otmp;
  315.  
  316.     for(otmp = invent; otmp; otmp = otmp->nobj)
  317.         if(otmp->otyp == LEASH &&
  318.                 otmp->leashmon == (int)mtmp->m_id)
  319.             otmp->leashmon = 0;
  320.     mtmp->mleashed = 0;
  321. }
  322.  
  323. void
  324. unleash_all()        /* player is about to die (for bones) */
  325. {
  326.     register struct obj *otmp;
  327.     register struct monst *mtmp;
  328.  
  329.     for(otmp = invent; otmp; otmp = otmp->nobj)
  330.         if(otmp->otyp == LEASH) otmp->leashmon = 0;
  331.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  332.         if(mtmp->mtame) mtmp->mleashed = 0;
  333. }
  334.  
  335. /* ARGSUSED */
  336. static void
  337. use_leash(obj)
  338. struct obj *obj;
  339. {
  340.     register int x, y;
  341.     register struct monst *mtmp;
  342.     int spotmon;
  343.  
  344.     if(!obj->leashmon && number_leashed() >= MAXLEASHED) {
  345.         You("cannot leash any more pets.");
  346.         return;
  347.     }
  348.  
  349.     if(!getdir(NULL)) return;
  350.  
  351.     x = u.ux + u.dx;
  352.     y = u.uy + u.dy;
  353.  
  354.     if((x == u.ux) && (y == u.uy)) {
  355.         pline("Leash yourself?  Very funny...");
  356.         return;
  357.     }
  358.  
  359.     if(!(mtmp = m_at(x, y))) {
  360.         pline("There is no creature there.");
  361.         return;
  362.     }
  363.  
  364.     spotmon = canseemon(mtmp) || sensemon(mtmp);
  365.  
  366.     if(!mtmp->mtame) {
  367.         if(!spotmon)
  368.         pline("There is no creature there.");
  369.         else
  370.         pline("%s %s leashed!", Monnam(mtmp), (!obj->leashmon) ?
  371.                 "cannot be" : "is not");
  372.         return;
  373.     }
  374.     if(!obj->leashmon) {
  375.         if(mtmp->mleashed) {
  376.             pline("This %s is already leashed.",
  377.                   spotmon ? l_monnam(mtmp) : "monster");
  378.             return;
  379.         }
  380.         You("slip the leash around %s%s.",
  381.             spotmon ? "your " : "", l_monnam(mtmp));
  382.         mtmp->mleashed = 1;
  383.         obj->leashmon = (int)mtmp->m_id;
  384.         if(mtmp->msleep)  mtmp->msleep = 0;
  385.         return;
  386.     }
  387.     if(obj->leashmon != (int)mtmp->m_id) {
  388.         pline("This leash is not attached to that creature.");
  389.         return;
  390.     } else {
  391.         if(obj->cursed) {
  392.             pline("The leash would not come off!");
  393.             obj->bknown = TRUE;
  394.             return;
  395.         }
  396.         mtmp->mleashed = 0;
  397.         obj->leashmon = 0;
  398.         You("remove the leash from %s%s.",
  399.             spotmon ? "your " : "", l_monnam(mtmp));
  400.     }
  401.     return;
  402. }
  403.  
  404. #endif /* OVLB */
  405. #ifdef OVL1
  406.  
  407. boolean
  408. next_to_u()
  409. {
  410.     register struct monst *mtmp;
  411.     register struct obj *otmp;
  412.  
  413.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  414.         if(mtmp->mleashed) {
  415.             if (distu(mtmp->mx,mtmp->my) > 2) mnexto(mtmp);
  416.             if (distu(mtmp->mx,mtmp->my) > 2) {
  417.                 for(otmp = invent; otmp; otmp = otmp->nobj)
  418.                 if(otmp->otyp == LEASH &&
  419.                     otmp->leashmon == (int)mtmp->m_id) {
  420.                     if(otmp->cursed) return(FALSE);
  421.                     You("feel %s leash go slack.",
  422.                     (number_leashed() > 1) ? "a" : "the");
  423.                     mtmp->mleashed = 0;
  424.                     otmp->leashmon = 0;
  425.                 }
  426.             }
  427.         }
  428.     return(TRUE);
  429. }
  430.  
  431. #endif /* OVL1 */
  432. #ifdef OVLB
  433. struct obj *
  434. get_mleash(mtmp)    /* assuming mtmp->mleashed has been checked */
  435. register struct monst *mtmp;
  436. {
  437.     register struct obj *otmp;
  438.  
  439.     otmp = invent;
  440.     while(otmp) {
  441.         if(otmp->otyp == LEASH && otmp->leashmon == (int)mtmp->m_id)
  442.             return(otmp);
  443.         otmp = otmp->nobj;
  444.     }
  445.     return((struct obj *)0);
  446. }
  447. #endif /* OVLB */
  448.  
  449. #endif /* WALKIES */
  450. #ifdef OVL0
  451.  
  452. #ifdef WALKIES
  453. void
  454. check_leash(x, y)
  455. register xchar x, y;
  456. {
  457.     register struct obj *otmp;
  458.     register struct monst *mtmp = fmon;
  459.  
  460.     for(otmp = invent; otmp; otmp = otmp->nobj)
  461.         if(otmp->otyp == LEASH && otmp->leashmon != 0) {
  462.         while(mtmp) {
  463.             if((int)mtmp->m_id == otmp->leashmon &&
  464.                 (dist2(u.ux,u.uy,mtmp->mx,mtmp->my) >
  465.                 dist2(x,y,mtmp->mx,mtmp->my))
  466.             ) {
  467.             if(otmp->cursed) {
  468.                 if(um_dist(mtmp->mx, mtmp->my, 5)) {
  469.                 pline("%s chokes to death!",Monnam(mtmp));
  470.                 mondied(mtmp);
  471.                 } else
  472.                 if(um_dist(mtmp->mx, mtmp->my, 3))
  473.                     pline("%s chokes on the leash!",
  474.                         Monnam(mtmp));
  475.             } else {
  476.                 if(um_dist(mtmp->mx, mtmp->my, 5)) {
  477.                 pline("%s leash snaps loose!",
  478.                     s_suffix(Monnam(mtmp)));
  479.                 m_unleash(mtmp);
  480.                 } else {
  481.                 if(um_dist(mtmp->mx, mtmp->my, 3)) {
  482.                     You("pull on the leash.");
  483. # ifdef SOUNDS
  484.                     if (mtmp->data->msound != MS_SILENT)
  485.                     switch(rn2(3)) {
  486.                     case 0:  growl(mtmp);    break;
  487.                     case 1:  yelp(mtmp);    break;
  488.                     default: whimper(mtmp); break;
  489.                     }
  490. # endif
  491.                 }
  492.                 }
  493.             }
  494.             }
  495.             mtmp = mtmp->nmon;
  496.         }
  497.         }
  498. }
  499.  
  500. #endif /* WALKIES */
  501.  
  502. #endif /* OVL0 */
  503. #ifdef OVLB
  504.  
  505. static boolean
  506. rm_waslit() {
  507.     register xchar x, y;
  508.  
  509.     if(levl[u.ux][u.uy].typ == ROOM && levl[u.ux][u.uy].waslit)
  510.     return(TRUE);
  511.     for(x = u.ux-2; x < u.ux+3; x++)
  512.     for(y = u.uy-1; y < u.uy+2; y++)
  513.         if(isok(x,y) && levl[x][y].waslit) return(TRUE);
  514.     return(FALSE);
  515. }
  516.  
  517. /* Change level topology.  Messes with vision tables and ignores things like
  518.  * boulders in the name of a nice effect.  Vision will get fixed up again
  519.  * immediately after the effect is complete.
  520.  */
  521. static void
  522. mkcavepos(x, y, dist, waslit, rockit)
  523.     xchar x,y;
  524.     int dist;
  525.     boolean waslit, rockit;
  526. {
  527.     register struct rm *lev;
  528.  
  529.     if(!isok(x,y)) return;
  530.     lev = &levl[x][y];
  531.  
  532.     if(rockit) {
  533.     register struct monst *mtmp;
  534.  
  535.     if(IS_ROCK(lev->typ)) return;
  536.     if(t_at(x, y)) return; /* don't cover the portal */
  537.     if ((mtmp = m_at(x, y)) != 0)    /* make sure crucial monsters survive */
  538.         if(!passes_walls(mtmp->data)) rloc(mtmp);
  539.     } else if(lev->typ == ROOM) return;
  540.  
  541.     unblock_point(x,y);    /* make sure vision knows this location is open */
  542.  
  543.     /* fake out saved state */
  544.     lev->seen = FALSE;
  545.     lev->doormask = 0;
  546.     if(dist < 3) lev->lit = (rockit ? FALSE : TRUE);
  547.     if(waslit) lev->waslit = (rockit ? FALSE : TRUE);
  548.     lev->horizontal = FALSE;
  549.     viz_array[y][x] = (dist < 3 ) ?
  550.     (IN_SIGHT|COULD_SEE) : /* short-circuit vision recalc */
  551.     COULD_SEE;
  552.     lev->typ = (rockit ? STONE : ROOM);
  553.     if(dist >= 3)
  554.     impossible("mkcavepos called with dist %d", dist);
  555.     if(Blind)
  556.     feel_location(x, y);
  557.     else newsym(x,y);
  558. }
  559.  
  560. static void
  561. mkcavearea(rockit)
  562. register boolean rockit;
  563. {
  564.     int dist;
  565.     xchar xmin = u.ux, xmax = u.ux;
  566.     xchar ymin = u.uy, ymax = u.uy;
  567.     register xchar i;
  568.     register boolean waslit = rm_waslit();
  569.  
  570.     if(rockit) pline("Crash!  The ceiling collapses around you!");
  571.     else pline("A mysterious force %s cave around you!",
  572.          (levl[u.ux][u.uy].typ == CORR) ? "creates a" : "extends the");
  573.     display_nhwindow(WIN_MESSAGE, TRUE);
  574.  
  575.     for(dist = 1; dist <= 2; dist++) {
  576.     xmin--; xmax++;
  577.  
  578.     /* top and bottom */
  579.     if(dist < 2) { /* the area is wider that it is high */
  580.         ymin--; ymax++;
  581.         for(i = xmin+1; i < xmax; i++) {
  582.         mkcavepos(i, ymin, dist, waslit, rockit);
  583.         mkcavepos(i, ymax, dist, waslit, rockit);
  584.         }
  585.     }
  586.  
  587.     /* left and right */
  588.     for(i = ymin; i <= ymax; i++) {
  589.         mkcavepos(xmin, i, dist, waslit, rockit);
  590.         mkcavepos(xmax, i, dist, waslit, rockit);
  591.     }
  592.  
  593.     flush_screen(1);    /* make sure the new glyphs shows up */
  594.     delay_output();
  595.     }
  596.  
  597.     if(!rockit && levl[u.ux][u.uy].typ == CORR) {
  598.     levl[u.ux][u.uy].typ = ROOM;
  599.     if(waslit) levl[u.ux][u.uy].waslit = TRUE;
  600.     newsym(u.ux, u.uy); /* in case player is invisible */
  601.     }
  602.  
  603.     vision_full_recalc = 1;    /* everything changed */
  604. }
  605.  
  606. STATIC_OVL int
  607. dig()
  608. {
  609.     register struct rm *lev;
  610.     register xchar dpx = dig_pos.x, dpy = dig_pos.y;
  611.  
  612.     lev = &levl[dpx][dpy];
  613.     /* perhaps a nymph stole your pick-axe while you were busy digging */
  614.     /* or perhaps you teleported away */
  615.     if(u.uswallow || !uwep || uwep->otyp != PICK_AXE ||
  616.         !on_level(&dig_level, &u.uz) ||
  617.         ((dig_down && (dpx != u.ux || dpy != u.uy)) ||
  618.          (!dig_down && distu(dpx,dpy) > 2)))
  619.         return(0);
  620.  
  621.     if (dig_down) {
  622.         struct trap *ttmp;
  623.  
  624.         if (On_stairs(u.ux, u.uy)) {
  625.         if (u.ux == xdnladder || u.ux == xupladder)
  626.              pline("The ladder resists your effort.");
  627.         else pline("The stairs are too hard to dig in.");
  628.         return(0);
  629.         } else if (IS_THRONE(levl[u.ux][u.uy].typ)) {
  630.         pline("The throne is too hard to break apart.");
  631.         return (0);
  632.         } else if (IS_ALTAR(levl[u.ux][u.uy].typ)) {
  633.         pline("The altar is too hard to break apart.");
  634.         return (0);
  635.         } else if (Is_airlevel(&u.uz)) {
  636.         You("cannot dig in thin air.");
  637.         return(0);
  638.         } else if (Is_waterlevel(&u.uz)) {
  639.         pline("The water splashes and subsides.");
  640.         return(0);
  641.         } else if ((ttmp = t_at(dpx, dpy)) &&
  642.             (ttmp->ttyp == MAGIC_PORTAL || !Can_dig_down(&u.uz))) {
  643.         pline("The %s here is too hard to dig in.",
  644.             surface(dpx,dpy));
  645.         return(0);
  646.         } else if (sobj_at(BOULDER, dpx, dpy)) {
  647.         pline("There isn't enough room to dig here.");
  648.         return(0);
  649.         }
  650.     } else { /* !dig_down */
  651.         if(IS_ROCK(lev->typ) && !may_dig(dpx,dpy)) {
  652.         pline("This wall is too hard to dig into.");
  653.         return(0);
  654.         }
  655.     }
  656.     if(Fumbling && !rn2(3)) {
  657.         switch(rn2(3)) {
  658.         case 0:  if(!welded(uwep)) {
  659.                  You("fumble and drop your %s.", xname(uwep));
  660.                  dropx(uwep);
  661.                  setuwep((struct obj *)0);
  662.              } else {
  663.                  pline("Ouch!  Your %s bounces and hits you!",
  664.                 xname(uwep));
  665.                  set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
  666.              }
  667.              break;
  668.         case 1:  pline("Bang!  You hit with the broad side of %s!",
  669.                    the(xname(uwep)));
  670.              break;
  671.         default: Your("swing misses its mark.");
  672.              break;
  673.         }
  674.         return(0);
  675.     }
  676.     dig_effort += 10 + abon() + uwep->spe - uwep->oeroded + rn2(5);
  677.     if(dig_down) {
  678.         register struct trap *ttmp;
  679.  
  680.         if(dig_effort > 250) {
  681.             (void) dighole(FALSE);
  682.             dig_level.dnum = 0;
  683.             dig_level.dlevel = -1;
  684.             return(0);    /* done with digging */
  685.         }
  686.  
  687.         if (dig_effort <= 50)
  688.             return(1);
  689.  
  690.         if ((ttmp = t_at(dpx,dpy)) &&
  691.             ((ttmp->ttyp == PIT) || (ttmp->ttyp == SPIKED_PIT) ||
  692.              (ttmp->ttyp == TRAPDOOR)))
  693.             return(1);
  694.  
  695.         if (IS_ALTAR(lev->typ)) {
  696.             altar_wrath(dpx, dpy);
  697.             angry_priest();
  698.         }
  699.  
  700.         if (dighole(TRUE)) {    /* make pit at <u.ux,u.uy> */
  701.             dig_level.dnum = 0;
  702.             dig_level.dlevel = -1;
  703.         }
  704.         return(0);
  705.     }
  706.     if(dig_effort > 100) {
  707.         register const char *digtxt, *dmgtxt = (const char*) 0;
  708.         register struct obj *obj;
  709.         register boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE);
  710.  
  711.         if ((obj = sobj_at(STATUE, dpx, dpy)) != 0) {
  712.             if (break_statue(obj))
  713.                 digtxt = "The statue shatters.";
  714.             else
  715.                 /* it was a statue trap; break_statue()
  716.                  * printed a message and updated the screen
  717.                  */
  718.                 digtxt = NULL;
  719.         } else if ((obj = sobj_at(BOULDER, dpx, dpy)) != 0) {
  720.             fracture_rock(obj);
  721.             digtxt = "The boulder falls apart.";
  722.         } else if(!lev->typ || lev->typ == SCORR) {
  723.             if(Is_earthlevel(&u.uz)) {
  724.                 if(uwep->blessed && !rn2(3)) {
  725.                 mkcavearea(FALSE);
  726.                 goto cleanup;
  727.                 } else if((uwep->cursed && !rn2(4)) ||
  728.                       (!uwep->blessed && !rn2(6))) {
  729.                 mkcavearea(TRUE);
  730.                 goto cleanup;
  731.                 }
  732.             }
  733.             lev->typ = CORR;
  734.             digtxt = "You succeed in cutting away some rock.";
  735.         } else if(IS_WALL(lev->typ)) {
  736.             if(shopedge) {
  737.                 add_damage(dpx, dpy, 10L * ACURRSTR);
  738.                 dmgtxt = "damage";
  739.             }
  740.             if (level.flags.is_maze_lev) {
  741.                 lev->typ = ROOM;
  742.             } else if (level.flags.is_cavernous_lev) {
  743.                 lev->typ = CORR;
  744.             } else {
  745.                 lev->typ = DOOR;
  746.                 lev->doormask = D_NODOOR;
  747.             }
  748.             digtxt = "You make an opening in the wall.";
  749.         } else if(lev->typ == SDOOR) {
  750.             lev->typ = DOOR;
  751.             digtxt = "You break through a secret door!";
  752.             if(!(lev->doormask & D_TRAPPED))
  753.                 lev->doormask = D_BROKEN;
  754.         } else if(closed_door(dpx, dpy)) {
  755.             digtxt = "You break through the door.";
  756.             if(shopedge) {
  757.                 add_damage(dpx, dpy, 400L);
  758.                 dmgtxt = "break";
  759.             }
  760.             if(!(lev->doormask & D_TRAPPED))
  761.                 lev->doormask = D_BROKEN;
  762.         } else return(0); /* statue or boulder got taken */
  763.  
  764.         unblock_point(dpx,dpy);    /* vision:  can see through */
  765.         if(Blind)
  766.             feel_location(dpx, dpy);
  767.         else
  768.             newsym(dpx, dpy);
  769.         if(digtxt) pline(digtxt);    /* after newsym */
  770.         if(dmgtxt)
  771.             pay_for_damage(dmgtxt);
  772.  
  773.         if(Is_earthlevel(&u.uz) && !rn2(3)) {
  774.             register struct monst *mtmp;
  775.  
  776.             switch(rn2(2)) {
  777.               case 0:
  778.             mtmp = makemon(&mons[PM_EARTH_ELEMENTAL], dpx, dpy);
  779.             break;
  780.               default:
  781.             mtmp = makemon(&mons[PM_XORN], dpx, dpy);
  782.             break;
  783.             }
  784.             if(mtmp) pline("The debris from your digging comes to life!");
  785.         }
  786.         if(IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) {
  787.             lev->doormask = D_NODOOR;
  788.             b_trapped("door", 0);
  789.             newsym(dpx, dpy);
  790.         }
  791. cleanup:
  792.         dig_level.dnum = 0;
  793.         dig_level.dlevel = -1;
  794.         return(0);
  795.     } else {
  796.         if(IS_WALL(lev->typ) || closed_door(dpx, dpy)) {
  797.             if(*in_rooms(dpx, dpy, SHOPBASE)) {
  798.             pline("This %s seems too hard to dig into.",
  799.                   IS_DOOR(lev->typ) ? "door" : "wall");
  800.             return(0);
  801.             }
  802.         } else if (!IS_ROCK(lev->typ) && !sobj_at(STATUE, dpx, dpy)
  803.                 && !sobj_at(BOULDER, dpx, dpy))
  804.             return(0); /* statue or boulder got taken */
  805.         if(!did_dig_msg) {
  806.             You("hit the %s with all your might.",
  807.             sobj_at(STATUE, dpx, dpy) ? "statue" :
  808.             sobj_at(BOULDER, dpx, dpy) ? "boulder" :
  809.             IS_DOOR(lev->typ) ? "door" : "rock");
  810.             did_dig_msg = TRUE;
  811.         }
  812.     }
  813.     return(1);
  814. }
  815.  
  816. /* When will hole be finished? Very rough indication used by shopkeeper. */
  817. int
  818. holetime() {
  819.     if(occupation != dig || !*u.ushops) return(-1);
  820.     return((250 - dig_effort)/20);
  821. }
  822.  
  823. /* Return typ of liquid to fill a hole with, or ROOM, if no liquid nearby */
  824. STATIC_OVL
  825. schar
  826. fillholetyp(x,y)
  827. int x, y;
  828. {
  829.     register int x1, y1;
  830.     int lo_x = max(1,x-1), hi_x = min(x+1,COLNO-1),
  831.     lo_y = max(0,y-1), hi_y = min(y+1,ROWNO-1);
  832.     int pool_cnt = 0, moat_cnt = 0, lava_cnt = 0;
  833.  
  834.     for (x1 = lo_x; x1 <= hi_x; x1++)
  835.     for (y1 = lo_y; y1 <= hi_y; y1++)
  836.         if (levl[x1][y1].typ == POOL)
  837.         pool_cnt++;
  838.         else if (levl[x1][y1].typ == MOAT ||
  839.             (levl[x1][y1].typ == DRAWBRIDGE_UP &&
  840.             (levl[x1][y1].drawbridgemask & DB_UNDER) == DB_MOAT))
  841.         moat_cnt++;
  842.         else if (levl[x1][y1].typ == LAVAPOOL ||
  843.             (levl[x1][y1].typ == DRAWBRIDGE_UP &&
  844.             (levl[x1][y1].drawbridgemask & DB_UNDER) == DB_LAVA))
  845.         lava_cnt++;
  846.     pool_cnt /= 3;        /* not as much liquid as the others */
  847.  
  848.     if (lava_cnt > moat_cnt + pool_cnt && rn2(lava_cnt + 1))
  849.     return LAVAPOOL;
  850.     else if (moat_cnt > 0 && rn2(moat_cnt + 1))
  851.     return MOAT;
  852.     else if (pool_cnt > 0 && rn2(pool_cnt + 1))
  853.     return POOL;
  854.     else
  855.     return ROOM;
  856. }
  857.  
  858. static void
  859. digactualhole(ttyp)
  860. int ttyp;
  861. {
  862.     struct obj *oldobjs, *newobjs;
  863.     register struct trap *ttmp;
  864.     boolean wont_fall = !!Levitation;
  865. #ifdef POLYSELF
  866.         wont_fall |= !!is_flyer(uasmon);
  867. #endif
  868.  
  869.     oldobjs = level.objects[u.ux][u.uy];
  870.     ttmp = maketrap(u.ux, u.uy, ttyp);
  871.     if (!ttmp) return;
  872.     newobjs = level.objects[u.ux][u.uy];
  873.     ttmp->tseen = 1;
  874.     if (Invisible) newsym(ttmp->tx,ttmp->ty);
  875.  
  876.     if (ttyp == PIT) {
  877.         if (!wont_fall) {
  878.             u.utrap = rn1(4,2);
  879.             u.utraptype = TT_PIT;
  880.             vision_full_recalc = 1;    /* vision limits change */
  881.         } else
  882.             u.utrap = 0;
  883.         if (oldobjs != newobjs)    /* something unearthed */
  884.             pickup(1);    /* detects pit */
  885.         else
  886.             You("dig a pit in the %s.", surface(u.ux, u.uy));
  887.  
  888.     } else {    /* TRAPDOOR */
  889.         pline("You dig a hole through the %s.", surface(u.ux,u.uy));
  890.  
  891.         if (*u.ushops)
  892.             add_damage(u.ux, u.uy, 0L);
  893.  
  894.         /* floor objects get a chance of falling down.
  895.          * the case where the hero does NOT fall down
  896.          * is treated here.  the case where the hero
  897.          * does fall down is treated in goto_level().
  898.          */
  899.         if (u.ustuck || wont_fall) {
  900.             if (newobjs)
  901.                 impact_drop((struct obj *)0, u.ux, u.uy, 0);
  902.             if (oldobjs != newobjs)
  903.                 pickup(1);
  904.         } else {
  905.             if (*u.ushops)
  906.                 shopdig(1);
  907. #ifdef WALKIES
  908.             if (!next_to_u()) {
  909.                 You("are jerked back by your pet!");
  910.                 if (newobjs)
  911.                 impact_drop((struct obj *)0, u.ux, u.uy, 0);
  912.                 if (oldobjs != newobjs)
  913.                 pickup(1);
  914.             } else
  915. #endif
  916.             {
  917.                 d_level newlevel;
  918.  
  919.                 You("fall through...");
  920.  
  921.                 /* earlier checks must ensure that the
  922.                  * destination level exists and is in the
  923.                  * present dungeon.
  924.                  */
  925.  
  926.                 newlevel.dnum = u.uz.dnum;
  927.                 newlevel.dlevel = u.uz.dlevel + 1;
  928.                 goto_level(&newlevel, FALSE, TRUE, FALSE);
  929.             }
  930.         }
  931.     }
  932. }
  933.  
  934. /* return TRUE if digging succeeded, FALSE otherwise */
  935. boolean
  936. dighole(pit_only)
  937. boolean pit_only;
  938. {
  939.     register struct trap *ttmp = t_at(u.ux, u.uy);
  940.     struct rm *lev = &levl[u.ux][u.uy];
  941.     struct obj *boulder_here;
  942.     schar typ;
  943.     boolean nohole = !Can_dig_down(&u.uz);
  944.  
  945.     if (ttmp && (ttmp->ttyp == MAGIC_PORTAL || nohole)) {
  946.         pline("The %s here is too hard to dig in.", surface(u.ux,u.uy));
  947.  
  948.     } else if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) {
  949.         pline("The %s sloshes furiously for a moment, then subsides.",
  950.             is_lava(u.ux, u.uy) ? "lava" : "water");
  951.         wake_nearby();    /* splashing */
  952.  
  953.     } else if (lev->typ == DRAWBRIDGE_DOWN) {
  954.         if (pit_only) {
  955.             pline("The drawbridge seems too hard to dig through.");
  956.             return FALSE;
  957.         } else {
  958.             destroy_drawbridge(u.ux, u.uy);
  959.             return TRUE;
  960.         }
  961.  
  962.     } else if ((boulder_here = sobj_at(BOULDER, u.ux, u.uy)) != 0) {
  963.         if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT)) {
  964.             pline("The boulder settles into the pit.");
  965.             ttmp->ttyp = PIT;     /* crush spikes */
  966.         } else {
  967.             /*
  968.              * digging makes a hole, but the boulder immediately
  969.              * fills it.  Final outcome:  no hole, no boulder.
  970.              */
  971.             pline("KADOOM! The boulder falls in!");
  972.  
  973.             /* destroy traps that emanate from the floor */
  974.             /* some of these are arbitrary -dlc */
  975.             if (ttmp && ((ttmp->ttyp == SQKY_BOARD) ||
  976.                      (ttmp->ttyp == BEAR_TRAP) ||
  977.                      (ttmp->ttyp == LANDMINE) ||
  978.                      (ttmp->ttyp == FIRE_TRAP) ||
  979.                      (ttmp->ttyp == TRAPDOOR) ||
  980.                      (ttmp->ttyp == TELEP_TRAP) ||
  981.                      (ttmp->ttyp == LEVEL_TELEP) ||
  982.                      (ttmp->ttyp == WEB) ||
  983.                      (ttmp->ttyp == MAGIC_TRAP) ||
  984.                      (ttmp->ttyp == ANTI_MAGIC))) {
  985.                 deltrap(ttmp);
  986.                 u.utrap = 0;
  987.                 u.utraptype = 0;
  988.             }
  989.         }
  990.         delobj(boulder_here);
  991.         return TRUE;
  992.  
  993.     } else if (lev->typ == DRAWBRIDGE_UP) {
  994.         /* must be floor or ice, other cases handled above */
  995.         /* dig "pit" and let fluid flow in (if possible) */
  996.         typ = fillholetyp(u.ux,u.uy);
  997.  
  998.         if (typ == ROOM) {
  999.             /*
  1000.              * We can't dig a hole here since that will destroy
  1001.              * the drawbridge.  The following is a cop-out. --dlc
  1002.              */
  1003.             pline("The %s here is too hard to dig in.",
  1004.                   surface(u.ux, u.uy));
  1005.             return FALSE;
  1006.         }
  1007.  
  1008.         lev->drawbridgemask &= ~DB_UNDER;
  1009.         lev->drawbridgemask |= (typ == LAVAPOOL) ? DB_LAVA : DB_MOAT;
  1010.  
  1011.  liquid_flow:
  1012.         newsym(u.ux,u.uy);
  1013.  
  1014.         pline("As you dig a pit, it fills with %s!",
  1015.               typ == LAVAPOOL ? "lava" : "water");
  1016.         if (!Levitation
  1017. #ifdef POLYSELF
  1018.            && !is_flyer(uasmon)
  1019. #endif
  1020.                     ) {
  1021.             if (typ == LAVAPOOL)
  1022.             (void) lava_effects();
  1023.             else if (!Wwalking)
  1024.             (void) drown();
  1025.         }
  1026.         return TRUE;
  1027.  
  1028.     } else if (IS_FOUNTAIN(lev->typ)) {
  1029.         dogushforth(FALSE);
  1030.         dryup(u.ux,u.uy);
  1031.         return TRUE;
  1032. #ifdef SINKS
  1033.     } else if (IS_SINK(lev->typ)) {
  1034.         breaksink(u.ux, u.uy);
  1035.         return TRUE;
  1036. #endif
  1037.     /* the following two are here for the wand of digging */
  1038.     } else if (IS_THRONE(lev->typ)) {
  1039.         pline("The throne is too hard to break apart.");
  1040.  
  1041.     } else if (IS_ALTAR(lev->typ)) {
  1042.         pline("The altar is too hard to break apart.");
  1043.  
  1044.     } else {
  1045.         typ = fillholetyp(u.ux,u.uy);
  1046.  
  1047.         if (typ != ROOM) {
  1048.             lev->typ = typ;
  1049.             goto liquid_flow;
  1050.         }
  1051.  
  1052.         /* finally we get to make a hole */
  1053.         if (nohole || pit_only)
  1054.             digactualhole(PIT);
  1055.         else
  1056.             digactualhole(TRAPDOOR);
  1057.  
  1058.         return TRUE;
  1059.     }
  1060.  
  1061.     return FALSE;
  1062. }
  1063.  
  1064. static boolean
  1065. wield_tool(obj)
  1066. struct obj *obj;
  1067. {
  1068.     if(welded(uwep)) {
  1069.         /* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */
  1070.         if(flags.verbose) {
  1071.             pline("Since your weapon is welded to your %s,",
  1072.                 bimanual(uwep) ?
  1073.                 (const char *)makeplural(body_part(HAND))
  1074.                 : body_part(HAND));
  1075.             pline("you cannot wield that %s.", xname(obj));
  1076.         }
  1077.         return(FALSE);
  1078.     }
  1079. # ifdef POLYSELF
  1080.     if(cantwield(uasmon)) {
  1081.         You("can't hold it strongly enough.");
  1082.         return(FALSE);
  1083.     }
  1084. # endif
  1085.     unweapon = TRUE;
  1086.     You("now wield %s.", doname(obj));
  1087.     setuwep(obj);
  1088.     if (uwep != obj) return(FALSE); /* rewielded old object after dying */
  1089.     return(TRUE);
  1090. }
  1091.  
  1092. static int
  1093. use_pick_axe(obj)
  1094. struct obj *obj;
  1095. {
  1096.     char dirsyms[12];
  1097.     char qbuf[QBUFSZ];
  1098.     register char *dsp = dirsyms;
  1099.     register const char *sdp = flags.num_pad ? ndir : sdir;
  1100.     register struct rm *lev;
  1101.     register int rx, ry, res = 0;
  1102.     register boolean isclosedoor;
  1103.  
  1104.     if(obj != uwep)
  1105.         if (!wield_tool(obj)) return(0);
  1106.         else res = 1;
  1107.  
  1108.     while(*sdp) {
  1109.         (void) movecmd(*sdp);    /* sets u.dx and u.dy and u.dz */
  1110.         rx = u.ux + u.dx;
  1111.         ry = u.uy + u.dy;
  1112.         if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) &&
  1113.             (IS_ROCK(levl[rx][ry].typ)
  1114.             || sobj_at(STATUE, rx, ry)
  1115.             || sobj_at(BOULDER, rx, ry))))
  1116.             *dsp++ = *sdp;
  1117.         sdp++;
  1118.     }
  1119.     *dsp = 0;
  1120.     Sprintf(qbuf, "In what direction do you want to dig? [%s]", dirsyms);
  1121.     if(!getdir(qbuf))
  1122.         return(res);
  1123.     if(u.uswallow && attack(u.ustuck)) /* return(1) */;
  1124.     else if(Underwater) {
  1125.         pline("Turbulence torpedoes your digging attempts.");
  1126.     } else if(u.dz < 0) {
  1127.         if(Levitation)
  1128.             You("don't have enough leverage.");
  1129.         else
  1130.             You("can't reach the ceiling.");
  1131.     } else if(!u.dx && !u.dy && !u.dz) {
  1132.         char buf[BUFSZ];
  1133.         int dam;
  1134.  
  1135.         dam = rnd(2) + dbon() + obj->spe;
  1136.         if (dam <= 0) dam = 1;
  1137.         You("hit yourself with your pick-axe.");
  1138.         /* self_pronoun() won't work twice in a sentence */
  1139.         Strcpy(buf, self_pronoun("killed %sself with %%s pick-axe",
  1140.             "him"));
  1141.         losehp(dam, self_pronoun(buf, "his"), NO_KILLER_PREFIX);
  1142.         flags.botl=1;
  1143.         return(1);
  1144.     } else if(u.dz == 0) {
  1145.         if(Stunned || (Confusion && !rn2(5))) confdir();
  1146.         rx = u.ux + u.dx;
  1147.         ry = u.uy + u.dy;
  1148.         if(!isok(rx, ry)) {
  1149.             pline("Clash!");
  1150.             return(1);
  1151.         }
  1152.         lev = &levl[rx][ry];
  1153.         if(MON_AT(rx, ry) && attack(m_at(rx, ry)))
  1154.             return(1);
  1155.         isclosedoor = closed_door(rx, ry);
  1156.         if(!IS_ROCK(lev->typ)
  1157.              && !isclosedoor
  1158.              && !sobj_at(STATUE, rx, ry)
  1159.              && !sobj_at(BOULDER, rx, ry)) {
  1160.             /* ACCESSIBLE or POOL */
  1161.             You("swing your %s through thin air.",
  1162.                 aobjnam(obj, NULL));
  1163.         } else {
  1164.             if(dig_pos.x != rx || dig_pos.y != ry
  1165.                 || !on_level(&dig_level, &u.uz) || dig_down) {
  1166.                 dig_down = FALSE;
  1167.                 dig_pos.x = rx;
  1168.                 dig_pos.y = ry;
  1169.                 assign_level(&dig_level, &u.uz);
  1170.                 dig_effort = 0;
  1171.                 You("start %s.",
  1172.                    sobj_at(STATUE, rx, ry) ?
  1173.                         "chipping the statue" :
  1174.                    sobj_at(BOULDER, rx, ry) ?
  1175.                         "hitting the boulder" :
  1176.                    isclosedoor ? "chopping at the door" :
  1177.                         "digging");
  1178.             } else
  1179.                 You("continue %s.",
  1180.                    sobj_at(STATUE, rx, ry) ?
  1181.                         "chipping the statue" :
  1182.                    sobj_at(BOULDER, rx, ry) ?
  1183.                         "hitting the boulder" :
  1184.                    isclosedoor ? "chopping at the door" :
  1185.                         "digging");
  1186.             did_dig_msg = FALSE;
  1187.             set_occupation(dig, "digging", 0);
  1188.         }
  1189.     } else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
  1190.         /* it must be air -- water checked above */
  1191.         You("swing your %s through thin air.", aobjnam(obj, NULL));
  1192.     } else if(Levitation) {
  1193.         You("can't reach the %s.", surface(u.ux,u.uy));
  1194.     } else if (is_pool(u.ux, u.uy)) {
  1195.         /* Monsters which swim also happen not to be able to dig */
  1196.         You("cannot stay underwater long enough.");
  1197.     } else {
  1198.         if(dig_pos.x != u.ux || dig_pos.y != u.uy
  1199.             || !on_level(&dig_level, &u.uz) || !dig_down) {
  1200.             dig_down = TRUE;
  1201.             dig_pos.x = u.ux;
  1202.             dig_pos.y = u.uy;
  1203.             assign_level(&dig_level, &u.uz);
  1204.             dig_effort = 0;
  1205.             You("start digging downward.");
  1206.             if(*u.ushops)
  1207.                 shopdig(0);
  1208.         } else
  1209.             You("continue digging downward.");
  1210.         did_dig_msg = FALSE;
  1211.         set_occupation(dig, "digging", 0);
  1212.     }
  1213.     return(1);
  1214. }
  1215.  
  1216. #define WEAK    3    /* from eat.c */
  1217.  
  1218. static char look_str[] = "look %s.";
  1219.  
  1220. static int
  1221. use_mirror(obj)
  1222. struct obj *obj;
  1223. {
  1224.     register struct monst *mtmp;
  1225.     register char mlet;
  1226.     boolean vis;
  1227.  
  1228.     if(!getdir(NULL)) return 0;
  1229.     if(obj->cursed && !rn2(2)) {
  1230.         if (!Blind)
  1231.             pline("The mirror fogs up and doesn't reflect!");
  1232.         return 1;
  1233.     }
  1234.     if(!u.dx && !u.dy && !u.dz) {
  1235.         if(!Blind && !Invisible) {
  1236. #ifdef POLYSELF
  1237.             if(u.umonnum == PM_FLOATING_EYE) {
  1238.             pline(Hallucination ?
  1239.                   "Yow!  The mirror stares back!" :
  1240.                   "Yikes!  You've frozen yourself!");
  1241.             nomul(-rnd((MAXULEV+6) - (int)u.ulevel));
  1242.             } else if (u.usym == S_VAMPIRE)
  1243.             You("don't have a reflection.");
  1244.             else if(u.umonnum == PM_UMBER_HULK) {
  1245.             pline("Huh?  That doesn't look like you!");
  1246.             make_confused(HConfusion + d(3,4),FALSE);
  1247.             } else
  1248. #endif
  1249.                if (Hallucination) You(look_str, hcolor());
  1250.             else if (Sick)
  1251.             You(look_str, "peaked");
  1252.             else if (u.uhs >= WEAK)
  1253.             You(look_str, "undernourished");
  1254.             else You("look as %s as ever.",
  1255.                 ACURR(A_CHA) > 14 ?
  1256.                 (poly_gender()==1 ? "beautiful" : "handsome") :
  1257.                 "ugly");
  1258.         } else {
  1259.             You("can't see your %s %s.",
  1260.                 ACURR(A_CHA) > 14 ?
  1261.                 (poly_gender()==1 ? "beautiful" : "handsome") :
  1262.                 "ugly",
  1263.                 body_part(FACE));
  1264.         }
  1265.         return 1;
  1266.     }
  1267.     if(u.uswallow) {
  1268.         if (!Blind) You("reflect %s's %s.", mon_nam(u.ustuck),
  1269.             is_animal(u.ustuck->data)? "stomach" : "interior");
  1270.         return 1;
  1271.     }
  1272.     if(Underwater) {
  1273.         You(Hallucination ?
  1274.             "give the fish a chance to fix their makeup." :
  1275.             "reflect the murky water.");
  1276.         return 1;
  1277.     }
  1278.     if(u.dz) {
  1279.         if (!Blind)
  1280.             You("reflect the %s.",
  1281.             (u.dz > 0) ? surface(u.ux,u.uy) : "ceiling");
  1282.         return 1;
  1283.     }
  1284.     if(!(mtmp = bhit(u.dx,u.dy,COLNO,INVIS_BEAM,
  1285.                     (int(*)())0,(int(*)())0,obj)) ||
  1286.        !haseyes(mtmp->data))
  1287.         return 1;
  1288.  
  1289.     vis = canseemon(mtmp);
  1290.     mlet = mtmp->data->mlet;
  1291.     if(mtmp->msleep) {
  1292.         if (vis)
  1293.             pline ("%s is too tired to look at your mirror.",
  1294.                 Monnam(mtmp));
  1295.     } else if (!mtmp->mcansee) {
  1296.         if (vis)
  1297.         pline("%s can't see anything right now.", Monnam(mtmp));
  1298.     /* some monsters do special things */
  1299.     } else if (mlet == S_VAMPIRE || mlet == S_GHOST) {
  1300.         if (vis)
  1301.         pline ("%s doesn't have a reflection.", Monnam(mtmp));
  1302.     } else if(!mtmp->mcan && mtmp->data == &mons[PM_MEDUSA]) {
  1303.         if (vis)
  1304.             pline("%s is turned to stone!", Monnam(mtmp));
  1305.         stoned = TRUE;
  1306.         killed(mtmp);
  1307.     } else if(!mtmp->mcan && !mtmp->minvis &&
  1308.                     mtmp->data == &mons[PM_FLOATING_EYE]) {
  1309.         int tmp = d((int)mtmp->m_lev, (int)mtmp->data->mattk[0].damd);
  1310.         if (!rn2(4)) tmp = 120;
  1311.     /* Note: floating eyes cannot use their abilities while invisible,
  1312.      * but Medusa and umber hulks can.
  1313.      */
  1314.         if (vis)
  1315.             pline("%s is frozen by its reflection.", Monnam(mtmp));
  1316.         else You("hear something stop moving.");
  1317.         mtmp->mcanmove = 0;
  1318.         if ( (int) mtmp->mfrozen + tmp > 127)
  1319.             mtmp->mfrozen = 127;
  1320.         else mtmp->mfrozen += tmp;
  1321.     } else if(!mtmp->mcan && mtmp->data == &mons[PM_UMBER_HULK]) {
  1322.         if (vis)
  1323.             pline ("%s confuses itself!", Monnam(mtmp));
  1324.         mtmp->mconf = 1;
  1325.     } else if(!mtmp->mcan && !mtmp->minvis && (mlet == S_NYMPH
  1326.                      || mtmp->data==&mons[PM_SUCCUBUS])) {
  1327.         if (vis) {
  1328.             pline ("%s admires herself in your mirror.", Monnam(mtmp));
  1329.             pline ("She takes it!");
  1330.         } else pline ("It steals your mirror!");
  1331.         setnotworn(obj); /* in case mirror was wielded */
  1332.         freeinv(obj);
  1333.         mpickobj(mtmp,obj);
  1334.         rloc(mtmp);
  1335.     } else if (mlet != S_UNICORN && !humanoid(mtmp->data) &&
  1336.             (!mtmp->minvis || perceives(mtmp->data)) && rn2(5)) {
  1337.         if (vis)
  1338.             pline ("%s is frightened by its reflection.",
  1339.                 Monnam(mtmp));
  1340.         mtmp->mflee = 1;
  1341.         mtmp->mfleetim += d(2,4);
  1342.     } else if (!Blind) {
  1343.         if (mtmp->minvis && !See_invisible)
  1344.             ;
  1345.         else if ((mtmp->minvis && !perceives(mtmp->data))
  1346.              || !haseyes(mtmp->data))
  1347.             pline("%s doesn't seem to notice its reflection.",
  1348.             Monnam(mtmp));
  1349.         else
  1350.             pline("%s ignores %s reflection.",
  1351.               Monnam(mtmp), his[pronoun_gender(mtmp)]);
  1352.     }
  1353.     return 1;
  1354. }
  1355.  
  1356. static void
  1357. use_bell(obj)
  1358. register struct obj *obj;
  1359. {
  1360.     You("ring %s.", the(xname(obj)));
  1361.  
  1362.     if(Underwater) {
  1363. #ifdef    AMIGA
  1364.         amii_speaker( obj, "AhDhGqEqDhEhAqDqFhGw", AMII_MUFFLED_VOLUME );
  1365. #endif
  1366.         pline("But the sound is muffled.");
  1367.         return;
  1368.     }
  1369.     if(obj->otyp == BELL) {
  1370.         if(u.uswallow) {
  1371.         pline(nothing_happens);
  1372.         return;
  1373.         }
  1374. #ifdef    AMIGA
  1375.         amii_speaker( obj, "ahdhgqeqdhehaqdqfhgw", AMII_MUFFLED_VOLUME );
  1376. #endif
  1377.         if(obj->cursed && !rn2(3)) {
  1378.         register struct monst *mtmp;
  1379.  
  1380.         if ((mtmp = makemon(&mons[PM_WOOD_NYMPH], u.ux, u.uy)) != 0)
  1381.            You("summon %s!", a_monnam(mtmp));
  1382.         }
  1383.         wake_nearby();
  1384.         return;
  1385.     }
  1386.  
  1387.     /* bell of opening */
  1388.     if(u.uswallow && !obj->blessed) {
  1389.         pline(nothing_happens);
  1390.         return;
  1391.     }
  1392.     if(obj->cursed) {
  1393.         coord mm;
  1394.         mm.x = u.ux;
  1395.         mm.y = u.uy;
  1396.         mkundead(&mm);
  1397. cursed_bell:
  1398.         wake_nearby();
  1399.         if(obj->spe > 0) obj->spe--;
  1400.         return;
  1401.     }
  1402.     if(invocation_pos(u.ux, u.uy) &&
  1403.              !On_stairs(u.ux, u.uy) && !u.uswallow) {
  1404.         pline("%s issues an unsettling shrill sound...", The(xname(obj)));
  1405. #ifdef    AMIGA
  1406.         amii_speaker( obj, "aefeaefeaefeaefeaefe", AMII_LOUDER_VOLUME );
  1407. #endif
  1408.         obj->age = moves;
  1409.         if(obj->spe > 0) obj->spe--;
  1410.         wake_nearby();
  1411.         obj->known = 1;
  1412.         return;
  1413.     }
  1414.     if(obj->blessed) {
  1415.         if(obj->spe > 0) {
  1416.         register int cnt = openit();
  1417.         if(cnt == -1) return; /* was swallowed */
  1418. #ifdef    AMIGA
  1419.         amii_speaker( obj, "ahahahDhEhCw", AMII_SOFT_VOLUME );
  1420. #endif
  1421.         switch(cnt) {
  1422.           case 0:  pline(nothing_happens); break;
  1423.           case 1:  pline("Something opens..."); break;
  1424.           default: pline("Things open around you..."); break;
  1425.         }
  1426.         if(cnt > 0) obj->known = 1;
  1427.         obj->spe--;
  1428.         } else pline(nothing_happens);
  1429.     } else {  /* uncursed */
  1430. #ifdef    AMIGA
  1431.         amii_speaker( obj, "AeFeaeFeAefegw", AMII_OKAY_VOLUME );
  1432. #endif
  1433.         if(obj->spe > 0) {
  1434.         register int cnt = findit();
  1435.         if(cnt == 0) pline(nothing_happens);
  1436.         else obj->known = 1;
  1437.         obj->spe--;
  1438.         } else {
  1439.         if(!rn2(3)) goto cursed_bell;
  1440.         else pline(nothing_happens);
  1441.         }
  1442.     }
  1443. }
  1444.  
  1445. static void
  1446. use_candelabrum(obj)
  1447. register struct obj *obj;
  1448. {
  1449.     if(Underwater) {
  1450.         You("cannot make fire under water.");
  1451.         return;
  1452.     }
  1453.     if(obj->lamplit) {
  1454.         You("snuff the candle%s.", obj->spe > 1 ? "s" : "");
  1455.         obj->lamplit = 0;
  1456.         check_lamps();
  1457.         return;
  1458.     }
  1459.     if(obj->spe <= 0) {
  1460.         pline("This %s has no candles.", xname(obj));
  1461.         return;
  1462.     }
  1463.     if(u.uswallow || obj->cursed) {
  1464.         pline("The candle%s flicker%s for a moment, then die%s.",
  1465.             obj->spe > 1 ? "s" : "",
  1466.             obj->spe > 1 ? "" : "s",
  1467.             obj->spe > 1 ? "" : "s");
  1468.         return;
  1469.     }
  1470.     if(obj->spe < 7) {
  1471.         pline("There %s only %d candle%s in %s.",
  1472.                obj->spe == 1 ? "is" : "are",
  1473.                obj->spe,
  1474.                obj->spe > 1 ? "s" : "",
  1475.                the(xname(obj)));
  1476.         if (!Blind)
  1477.             pline("%s lit.  %s shines dimly.",
  1478.                obj->spe == 1 ? "It is" : "They are", The(xname(obj)));
  1479.     } else {
  1480.         pline("%s's candles burn%s", The(xname(obj)),
  1481.             (Blind ? "." : " brightly!"));
  1482.     }
  1483.     if (!invocation_pos(u.ux, u.uy)) {
  1484.         pline("The candle%s being rapidly consumed!",
  1485.             (obj->spe > 1 ? "s are" : " is"));
  1486.         obj->age /= 2;
  1487.     } else {
  1488.         if(obj->spe == 7) {
  1489.             if (Blind)
  1490.               pline("%s radiates a strange warmth!", The(xname(obj)));
  1491.             else
  1492.               pline("%s glows with a strange light!", The(xname(obj)));
  1493.         }
  1494.         obj->known = 1;
  1495.     }
  1496.     obj->lamplit = 1;
  1497.     check_lamps();
  1498. }
  1499.  
  1500. static void
  1501. use_candle(obj)
  1502. register struct obj *obj;
  1503. {
  1504.  
  1505.     register struct obj *otmp;
  1506.     char qbuf[QBUFSZ];
  1507.  
  1508.     if(obj->lamplit) {
  1509.         use_lamp(obj);
  1510.         return;
  1511.     }
  1512.  
  1513.     if(u.uswallow) {
  1514.         You("don't have enough elbow-room to maneuver.");
  1515.         return;
  1516.     }
  1517.     if(Underwater) {
  1518.         pline("Sorry, fire and water don't mix.");
  1519.         return;
  1520.     }
  1521.  
  1522.     for(otmp = invent; otmp; otmp = otmp->nobj) {
  1523.         if(otmp->otyp == CANDELABRUM_OF_INVOCATION && otmp->spe < 7)
  1524.             break;
  1525.     }
  1526.     if(!otmp || otmp->spe == 7) {
  1527.         use_lamp(obj);
  1528.         return;
  1529.     }
  1530.  
  1531.     Sprintf(qbuf, "Attach %s", the(xname(obj)));
  1532.     Sprintf(eos(qbuf), " to %s?", the(xname(otmp)));
  1533.     if(yn(qbuf) == 'n') {
  1534.         You("try to light %s...", the(xname(obj)));
  1535.         use_lamp(obj);
  1536.         return;
  1537.     } else {
  1538.         register long needed = 7L - (long)otmp->spe;
  1539.  
  1540.         You("attach %ld%s candle%s to %s.",
  1541.             obj->quan >= needed ? needed : obj->quan,
  1542.             !otmp->spe ? "" : " more",
  1543.             (needed > 1L && obj->quan > 1L) ? "s" : "",
  1544.             the(xname(otmp)));
  1545.         if(otmp->lamplit)
  1546.             pline("The new candle%s magically ignite%s!",
  1547.                 (needed > 1L && obj->quan > 1L) ? "s" : "",
  1548.                 (needed > 1L && obj->quan > 1L) ? "" : "s");
  1549.         if(obj->unpaid)
  1550.             verbalize("You burn %s, you bought %s!",
  1551.                 (needed > 1L && obj->quan > 1L) ? "them" : "it",
  1552.                 (needed > 1L && obj->quan > 1L) ? "them" : "it");
  1553.         if(!otmp->spe || otmp->age > obj->age)
  1554.             otmp->age = obj->age;
  1555.         if(obj->quan > needed) {
  1556.             if(obj->unpaid) {
  1557.             /* this is a hack, until we re-write the billing */
  1558.             /* code to accommodate such cases directly. IM*/
  1559.             register long delta = obj->quan - needed;
  1560.  
  1561.             subfrombill(obj, shop_keeper(*u.ushops));
  1562.             obj->quan = needed;
  1563.             addtobill(obj, TRUE, FALSE, TRUE);
  1564.             bill_dummy_object(obj);
  1565.             obj->quan = delta;
  1566.             addtobill(obj, TRUE, FALSE, TRUE);
  1567.              } else {
  1568.             obj->quan -= needed;
  1569.              }
  1570.              otmp->spe += (int)needed;
  1571.         } else {
  1572.             otmp->spe += (int)obj->quan;
  1573.             freeinv(obj);
  1574.             obfree(obj, (struct obj *)0);
  1575.         }
  1576.         if(needed < 7L && otmp->spe == 7)
  1577.             pline("%s has now seven%s candles attached.",
  1578.             The(xname(otmp)), otmp->lamplit ? " lit" : "");
  1579.     }
  1580. }
  1581.  
  1582. boolean
  1583. snuff_candle(otmp)  /* call in drop, throw, and put in box, etc. */
  1584. register struct obj *otmp;
  1585. {
  1586.     register boolean candle = Is_candle(otmp);
  1587.  
  1588.     if ((candle || otmp->otyp == CANDELABRUM_OF_INVOCATION) &&
  1589.         otmp->lamplit) {
  1590.         register boolean many = candle ? otmp->quan > 1L : otmp->spe > 1;
  1591.         if (!Blind)
  1592.         pline("The %scandle%s flame%s extinguished.",
  1593.               (candle ? "" : "candelabrum's "),
  1594.               (many ? "s'" : "'s"), (many ? "s are" : " is"));
  1595.        otmp->lamplit = 0;
  1596.        check_lamps();
  1597.        return(TRUE);
  1598.     }
  1599.     return(FALSE);
  1600. }
  1601.  
  1602. boolean
  1603. snuff_lit(obj)
  1604. struct obj *obj;
  1605. {
  1606.     if(obj->lamplit) {
  1607.         if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
  1608.                 obj->otyp == BRASS_LANTERN) {
  1609.             if (!Blind) Your("lamp is now off.");
  1610.             obj->lamplit = 0;
  1611.             check_lamps();
  1612.             return(TRUE);
  1613.         }
  1614.  
  1615.         if(snuff_candle(obj)) return(TRUE);
  1616.     }
  1617.  
  1618.     return(FALSE);
  1619. }
  1620.  
  1621. static void
  1622. use_lamp(obj)
  1623. struct obj *obj;
  1624. {
  1625.     if(Underwater) {
  1626.         pline("This is not a diving lamp.");
  1627.         return;
  1628.     }
  1629.     if(obj->lamplit) {
  1630.         if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
  1631.                 obj->otyp == BRASS_LANTERN)
  1632.             Your("lamp is now off.");
  1633.         else
  1634.             You("snuff out %s.", the(xname(obj)));
  1635.         obj->lamplit = 0;
  1636.         check_lamps();
  1637.         return;
  1638.     }
  1639.     if (!Is_candle(obj) && obj->spe <= 0) {
  1640.         if (obj->otyp == BRASS_LANTERN)
  1641.             Your("lamp has run out of power.");
  1642.         else pline("This %s has no oil.", xname(obj));
  1643.         return;
  1644.     }
  1645.     if(obj->cursed && !rn2(2))
  1646.         pline("%s flicker%s for a moment, then die%s.",
  1647.                The(xname(obj)),
  1648.                obj->quan > 1L ? "" : "s",
  1649.                obj->quan > 1L ? "" : "s");
  1650.     else {
  1651.         if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
  1652.                 obj->otyp == BRASS_LANTERN)
  1653.             Your("lamp is now on.");
  1654.         else
  1655.             pline("%s%s flame%s burn%s%s", The(xname(obj)),
  1656.             obj->quan > 1L ? "'" : "'s",
  1657.             obj->quan > 1L ? "s" : "",
  1658.             obj->quan > 1L ? "" : "s",
  1659.             Blind ? "." : " brightly!");
  1660.         obj->lamplit = 1;
  1661.         check_lamps();
  1662.         if (obj->unpaid && Is_candle(obj) &&
  1663.             obj->age == 20L * (long)objects[obj->otyp].oc_cost) {
  1664.             const char *it_them = obj->quan > 1L ? "them" : "it";
  1665.             verbalize("You burn %s, you bought %s!", it_them, it_them);
  1666.             bill_dummy_object(obj);
  1667.         }
  1668.     }
  1669. }
  1670.  
  1671. void
  1672. check_lamps()
  1673. {
  1674.     register struct obj *obj;
  1675.     int lamps = 0;
  1676.  
  1677.     for(obj = invent; obj; obj = obj->nobj)
  1678.         if (obj->lamplit) {
  1679.             lamps++;
  1680.             break;
  1681.         }
  1682.  
  1683.     if (lamps && u.nv_range == 1) {
  1684.         u.nv_range = 3;
  1685.         vision_full_recalc = 1;
  1686.     } else if (!lamps && u.nv_range == 3) {
  1687.         u.nv_range = 1;
  1688.         vision_full_recalc = 1;
  1689.     }
  1690. }
  1691.  
  1692. static NEARDATA const char cuddly[] = { TOOL_CLASS, 0 };
  1693.  
  1694. int
  1695. dorub()
  1696. {
  1697.     struct obj *obj = getobj(cuddly, "rub");
  1698.  
  1699.     if(!obj || (obj != uwep && !wield_tool(obj))) return 0;
  1700.  
  1701.     /* now uwep is obj */
  1702.     if (uwep->otyp == MAGIC_LAMP) {
  1703.         if (uwep->spe > 0 && !rn2(3)) {
  1704.         djinni_from_bottle(uwep);
  1705.         makeknown(MAGIC_LAMP);
  1706.         uwep->otyp = OIL_LAMP;
  1707.         uwep->spe = 1; /* for safety */
  1708.         uwep->age = rn1(500,1000);
  1709.         } else if (rn2(2) && !Blind)
  1710.         You("see a puff of smoke.");
  1711.         else pline(nothing_happens);
  1712.     } else if (obj->otyp == BRASS_LANTERN) {
  1713.         /* message from Adventure */
  1714.         pline("Rubbing the electric lamp is not particularly rewarding.");
  1715.         pline("Anyway, nothing exciting happens.");
  1716.     } else pline(nothing_happens);
  1717.     return 1;
  1718. }
  1719.  
  1720. int
  1721. dojump()
  1722. {
  1723.     coord cc;
  1724.     register struct monst *mtmp;
  1725.     if (!Jumping || Levitation) {
  1726.         You("can't jump very far.");
  1727.         return 0;
  1728.     } else if (u.uswallow) {
  1729.         pline("You've got to be kidding!");
  1730.         return 0;
  1731.     } else if (u.uinwater) {
  1732.         pline("This calls for swimming, not jumping!");
  1733.         return 0;
  1734.     } else if (u.ustuck) {
  1735.         You("cannot escape from %s!", mon_nam(u.ustuck));
  1736.         return 0;
  1737.     } else if (near_capacity() > UNENCUMBERED) {
  1738.         You("are carrying too much to jump!");
  1739.         return 0;
  1740.     } else if (u.uhunger <= 100 || ACURR(A_STR) < 6) {
  1741.         You("lack the strength to jump!");
  1742.         return 0;
  1743.     }
  1744.     pline("Where do you want to jump?");
  1745.     cc.x = u.ux;
  1746.     cc.y = u.uy;
  1747.     getpos(&cc, TRUE, "the desired position");
  1748.     if(cc.x == -10) return 0; /* user pressed esc */
  1749.     if (!(Jumping & ~INTRINSIC) && distu(cc.x, cc.y) != 5) {
  1750.         pline("Illegal move!");
  1751.         return 0;
  1752.     } else if (distu(cc.x, cc.y) > 9) {
  1753.         pline("Too far!");
  1754.         return 0;
  1755.     } else if (!cansee(cc.x, cc.y)) {
  1756.         You("cannot see where to land!");
  1757.         return 0;
  1758.     } else if ((mtmp = m_at(cc.x, cc.y)) != 0) {
  1759.         You("cannot trample %s!", mon_nam(mtmp));
  1760.         return 0;
  1761.     } else if (!isok(cc.x, cc.y) ||
  1762.            ((IS_ROCK(levl[cc.x][cc.y].typ) ||
  1763.              sobj_at(BOULDER, cc.x, cc.y) || closed_door(cc.x, cc.y))
  1764. #ifdef POLYSELF
  1765.             && !(passes_walls(uasmon) && may_passwall(cc.x, cc.y))
  1766. #endif
  1767.             )) {
  1768.             You("cannot jump there!");
  1769.             return 0;
  1770.     } else {
  1771.         if(u.utrap)
  1772.         switch(u.utraptype) {
  1773.         case TT_BEARTRAP: {
  1774.             register long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
  1775.             You("rip yourself free of the bear trap!  Ouch!");
  1776.             losehp(rnd(10), "jumping out of a bear trap", KILLED_BY);
  1777.             set_wounded_legs(side, rn1(1000,500));
  1778.             break;
  1779.           }
  1780.         case TT_PIT:
  1781.             You("leap from the pit!");
  1782.             break;
  1783.         case TT_WEB:
  1784.             You("tear the web apart as you pull yourself free!");
  1785.             deltrap(t_at(u.ux,u.uy));
  1786.             break;
  1787.         case TT_LAVA:
  1788.             You("pull yourself above the lava!");
  1789.             u.utrap = 0;
  1790.             return 1;
  1791.         case TT_INFLOOR:
  1792.             You("strain your %s, but you're still stuck in the floor.",
  1793.             makeplural(body_part(LEG)));
  1794.             set_wounded_legs(LEFT_SIDE, rn1(10, 11));
  1795.             set_wounded_legs(RIGHT_SIDE, rn1(10, 11));
  1796.             return 1;
  1797.         }
  1798.  
  1799.         teleds(cc.x, cc.y);
  1800.         nomul(-1);
  1801.         nomovemsg = "";
  1802.         morehungry(rnd(25));
  1803.         return 1;
  1804.     }
  1805. }
  1806.  
  1807. boolean
  1808. tinnable(corpse)
  1809. struct obj *corpse;
  1810. {
  1811.     if (corpse->oeaten) return 0;
  1812.     if (!mons[corpse->corpsenm].cnutrit) return 0;
  1813.     return 1;
  1814. }
  1815.  
  1816. static void
  1817. use_tinning_kit(obj)
  1818. register struct obj *obj;
  1819. {
  1820.     register struct obj *corpse, *can;
  1821.  
  1822.     /* This takes only 1 move.  If this is to be changed to take many
  1823.      * moves, we've got to deal with decaying corpses...
  1824.      */
  1825.     if (!(corpse = floorfood("tin", 2))) return;
  1826.     if (corpse->oeaten) {
  1827.         You("cannot tin something which is partly eaten.");
  1828.         return;
  1829.     }
  1830.     if ((corpse->corpsenm == PM_COCKATRICE)
  1831. #ifdef POLYSELF
  1832.         && !resists_ston(uasmon)
  1833. #endif
  1834.         && !uarmg) {
  1835. pline("Tinning a cockatrice without wearing gloves is a fatal mistake...");
  1836. #if defined(POLYSELF)
  1837. /* this will have to change if more monsters can poly */
  1838.         if(!(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)))
  1839. #endif
  1840.         {
  1841.         You("turn to stone...");
  1842.         killer_format = KILLED_BY;
  1843.         killer = "trying to tin a cockatrice without gloves";
  1844.         done(STONING);
  1845.         }
  1846.     }
  1847.     if (is_rider(&mons[corpse->corpsenm])) {
  1848.         revive_corpse(corpse, 0, FALSE);
  1849.         verbalize("Yes...  But War does not preserve its enemies...");
  1850.         return;
  1851.     }
  1852.     if (mons[corpse->corpsenm].cnutrit == 0) {
  1853.         pline("That's too insubstantial to tin.");
  1854.         return;
  1855.     }
  1856.     if ((can = mksobj(TIN, FALSE, FALSE)) != 0) {
  1857.         can->corpsenm = corpse->corpsenm;
  1858.         can->cursed = obj->cursed;
  1859.         can->blessed = obj->blessed;
  1860.         can->owt = weight(can);
  1861.         can->known = 1;
  1862.         can->spe = -1;  /* Mark tinned tins. No spinach allowed... */
  1863.         if (carried(corpse)) {
  1864.         if(corpse->unpaid) {
  1865.             verbalize("You tin it, you bought it!");
  1866.             bill_dummy_object(corpse);
  1867.         }
  1868.         useup(corpse);
  1869.         } else {
  1870.         if(costly_spot(corpse->ox, corpse->oy) &&
  1871.               !corpse->no_charge) {
  1872.             verbalize("You tin it, you bought it!");
  1873.             bill_dummy_object(corpse);
  1874.         }
  1875.         useupf(corpse);
  1876.         }
  1877.         can = hold_another_object(can, "You make, but cannot pick up, %s.",
  1878.                       doname(can), (const char *)0);
  1879.     } else impossible("Tinning failed.");
  1880. }
  1881.  
  1882. void
  1883. use_unicorn_horn(obj)
  1884. struct obj *obj;
  1885. {
  1886.     boolean blessed = (obj && obj->blessed);
  1887.     boolean did_something = FALSE;
  1888.  
  1889.     if (obj && obj->cursed) {
  1890.         switch (rn2(6)) {
  1891.             static char buf[BUFSZ];
  1892.             case 0: make_sick(Sick ? Sick/4 + 1L : (long) rn1(ACURR(A_CON), 20), TRUE);
  1893.                 Strcpy(buf, xname(obj));
  1894.                 u.usick_cause = (const char *)buf;
  1895.                 break;
  1896.             case 1: make_blinded(Blinded + (long) rnd(100), TRUE);
  1897.                 break;
  1898.             case 2: if (!Confusion)
  1899.                 You("suddenly feel %s.",
  1900.                     Hallucination ? "trippy" : "confused");
  1901.                 make_confused(HConfusion + (long) rnd(100), TRUE);
  1902.                 break;
  1903.             case 3: make_stunned(HStun + (long) rnd(100), TRUE);
  1904.                 break;
  1905.             case 4: (void) adjattrib(rn2(6), -1, FALSE);
  1906.                 break;
  1907.             case 5: make_hallucinated(HHallucination + (long) rnd(100),
  1908.                 TRUE, 0L);
  1909.                 break;
  1910.         }
  1911.         return;
  1912.     }
  1913.  
  1914.     if (Sick) {
  1915.         make_sick(0L, TRUE);
  1916.         did_something++;
  1917.     }
  1918.     if (Blinded > (long)(u.ucreamed+1) && (!did_something || blessed)) {
  1919.         make_blinded(u.ucreamed ? (long)(u.ucreamed+1) : 0L, TRUE);
  1920.         did_something++;
  1921.     }
  1922.     if (Hallucination && (!did_something || blessed)) {
  1923.         make_hallucinated(0L, TRUE, 0L);
  1924.         did_something++;
  1925.     }
  1926.     if (Vomiting && (!did_something || blessed)) {
  1927.         make_vomiting(0L, TRUE);
  1928.         did_something++;
  1929.     }
  1930.     if (HConfusion && (!did_something || blessed)) {
  1931.         make_confused(0L, TRUE);
  1932.         did_something++;
  1933.     }
  1934.     if (HStun && (!did_something || blessed)) {
  1935.         make_stunned(0L, TRUE);
  1936.         did_something++;
  1937.     }
  1938.     if (!did_something || blessed) {
  1939.         register int j;
  1940.         int did_stat = 0;
  1941.         int i = rn2(A_MAX);
  1942.         for(j=0; j<A_MAX; j++) {
  1943.             /* don't recover strength lost while hungry */
  1944.             if ((blessed || j==i) &&
  1945.                 ((j != A_STR || u.uhs < WEAK)
  1946.                 ? (ABASE(j) < AMAX(j))
  1947.                 : (ABASE(A_STR) < (AMAX(A_STR) - 1)))) {
  1948.                 did_something++;
  1949.                 /* They may have to use it several times... */
  1950.                 if (!did_stat) {
  1951.                     did_stat++;
  1952.                     pline("This makes you feel good!");
  1953.                 }
  1954.                 ABASE(j)++;
  1955.                 flags.botl = 1;
  1956.             }
  1957.         }
  1958.     }
  1959.     if (!did_something) pline(nothing_happens);
  1960. }
  1961.  
  1962. static void
  1963. use_figurine(obj)
  1964. register struct obj *obj;
  1965. {
  1966.     xchar x, y;
  1967.  
  1968.     if(!getdir(NULL)) {
  1969.         flags.move = multi = 0;
  1970.         return;
  1971.     }
  1972.     x = u.ux + u.dx; y = u.uy + u.dy;
  1973.     if (!isok(x,y)) {
  1974.         You("cannot put the figurine there.");
  1975.         return;
  1976.     }
  1977.     if (IS_ROCK(levl[x][y].typ) &&
  1978.         !(passes_walls(&mons[obj->corpsenm]) && may_passwall(x,y))) {
  1979.         You("cannot place a figurine in solid rock!");
  1980.         return;
  1981.     }
  1982.     if (sobj_at(BOULDER,x,y) && !passes_walls(&mons[obj->corpsenm])
  1983.             && !throws_rocks(&mons[obj->corpsenm])) {
  1984.         You("cannot fit the figurine on the boulder.");
  1985.         return;
  1986.     }
  1987.     You("%s and it transforms.",
  1988.         (u.dx||u.dy) ? "set the figurine beside you" :
  1989.         (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) ?
  1990.         "release the figurine" :
  1991.         (u.dz < 0 ?
  1992.         "toss the figurine into the air" :
  1993.         "set the figurine on the ground"));
  1994.     make_familiar(obj, u.ux+u.dx, u.uy+u.dy);
  1995.     useup(obj);
  1996. }
  1997.  
  1998. static NEARDATA const char lubricables[] = { ALL_CLASSES, ALLOW_NONE, 0 };
  1999.  
  2000. static void
  2001. use_grease(obj)
  2002. struct obj *obj;
  2003. {
  2004.     struct obj *otmp;
  2005.  
  2006.     if (Glib) {
  2007.         dropx(obj);
  2008.         pline("%s slips from your %s.", The(xname(obj)),
  2009.           makeplural(body_part(FINGER)));
  2010.         return;
  2011.     }
  2012.  
  2013.     if (obj->spe > 0) {
  2014.         if ((obj->cursed || Fumbling) && !rn2(2)) {
  2015.             obj->spe--;
  2016.             check_unpaid(obj);
  2017.             dropx(obj);
  2018.             pline("%s slips from your %s.", The(xname(obj)),
  2019.                   makeplural(body_part(FINGER)));
  2020.             return;
  2021.         }
  2022.         otmp = getobj(lubricables, "grease");
  2023.         if (!otmp) return;
  2024.         obj->spe--;
  2025.         check_unpaid(obj);
  2026.         if (otmp != &zeroobj) {
  2027.             You("cover your %s with a thick layer of grease.",
  2028.                 xname(otmp));
  2029.             otmp->greased = 1;
  2030.         } else {
  2031.             Glib += rnd(15);
  2032.             You("coat your %s with grease.",
  2033.                 makeplural(body_part(FINGER)));
  2034.         }
  2035.     } else {
  2036.         pline("%s %s empty.", The(xname(obj)),
  2037.             obj->known ? "is" : "seems to be");
  2038.     }
  2039. }
  2040.  
  2041. int
  2042. doapply()
  2043. {
  2044.     register struct obj *obj;
  2045.     register int res = 1;
  2046.  
  2047.     if(check_capacity(NULL)) return (0);
  2048.     obj = getobj(tools, "use or apply");
  2049.     if(!obj) return 0;
  2050.  
  2051.     check_unpaid(obj);
  2052.  
  2053.     switch(obj->otyp){
  2054.     case BLINDFOLD:
  2055.         if (obj == ublindf) {
  2056.             if(cursed(obj)) break;
  2057.             else Blindf_off(obj);
  2058.         }
  2059.         else if (!ublindf) Blindf_on(obj);
  2060.         else You("are already %s.", ublindf->otyp == TOWEL ?
  2061.              "covered by a towel" : "wearing a blindfold");
  2062.         break;
  2063.     case LARGE_BOX:
  2064.     case CHEST:
  2065.     case ICE_BOX:
  2066.     case SACK:
  2067.     case BAG_OF_HOLDING:
  2068.     case OILSKIN_SACK:
  2069.         res = use_container(obj, 1);
  2070.         break;
  2071.     case BAG_OF_TRICKS:
  2072.         if(obj->spe > 0) {
  2073.             register int cnt = 1;
  2074.  
  2075.             obj->spe--;
  2076.             check_unpaid(obj);
  2077.             if(!rn2(23)) cnt += rn2(7) + 1;
  2078.             while(cnt--)
  2079.                 (void) makemon((struct permonst *) 0, u.ux, u.uy);
  2080.             makeknown(BAG_OF_TRICKS);
  2081.         } else
  2082.             pline(nothing_happens);
  2083.         break;
  2084.     case CAN_OF_GREASE:
  2085.         use_grease(obj);
  2086.         break;
  2087.     case LOCK_PICK:
  2088. #ifdef TOURIST
  2089.     case CREDIT_CARD:
  2090. #endif
  2091.     case SKELETON_KEY:
  2092.         (void) pick_lock(obj);
  2093.         break;
  2094.     case PICK_AXE:
  2095.         res = use_pick_axe(obj);
  2096.         break;
  2097.     case TINNING_KIT:
  2098.         use_tinning_kit(obj);
  2099.         break;
  2100. #ifdef WALKIES
  2101.     case LEASH:
  2102.         use_leash(obj);
  2103.         break;
  2104. #endif
  2105.     case MAGIC_WHISTLE:
  2106.         use_magic_whistle(obj);
  2107.         break;
  2108.     case TIN_WHISTLE:
  2109.         use_whistle(obj);
  2110.         break;
  2111.     case STETHOSCOPE:
  2112.         res = 0;
  2113.         use_stethoscope(obj);
  2114.         break;
  2115.     case MIRROR:
  2116.         res = use_mirror(obj);
  2117.         break;
  2118.     case BELL:
  2119.     case BELL_OF_OPENING:
  2120.         use_bell(obj);
  2121.         break;
  2122.     case CANDELABRUM_OF_INVOCATION:
  2123.         use_candelabrum(obj);
  2124.         break;
  2125.     case WAX_CANDLE:
  2126.     case TALLOW_CANDLE:
  2127.         use_candle(obj);
  2128.         break;
  2129.     case OIL_LAMP:
  2130.     case MAGIC_LAMP:
  2131.     case BRASS_LANTERN:
  2132.         use_lamp(obj);
  2133.         break;
  2134. #ifdef TOURIST
  2135.     case EXPENSIVE_CAMERA:
  2136.         res = use_camera(obj);
  2137.         break;
  2138. #endif
  2139.     case TOWEL:
  2140.         res = use_towel(obj);
  2141.         break;
  2142.     case CRYSTAL_BALL:
  2143.         use_crystal_ball(obj);
  2144.         break;
  2145.     case MAGIC_MARKER:
  2146.         res = dowrite(obj);
  2147.         break;
  2148.     case TIN_OPENER:
  2149.         if(!carrying(TIN)) {
  2150.             You("have no tin to open.");
  2151.             goto xit;
  2152.         }
  2153.         You("cannot open a tin without eating or discarding its contents.");
  2154.         if(flags.verbose)
  2155.             pline("In order to eat, use the 'e' command.");
  2156.         if(obj != uwep)
  2157.     pline("Opening the tin will be much easier if you wield the tin opener.");
  2158.         goto xit;
  2159.  
  2160.     case FIGURINE:
  2161.         use_figurine(obj);
  2162.         break;
  2163.     case UNICORN_HORN:
  2164.         use_unicorn_horn(obj);
  2165.         break;
  2166.     case WOODEN_FLUTE:
  2167.     case MAGIC_FLUTE:
  2168.     case TOOLED_HORN:
  2169.     case FROST_HORN:
  2170.     case FIRE_HORN:
  2171.     case WOODEN_HARP:
  2172.     case MAGIC_HARP:
  2173.     case BUGLE:
  2174.     case LEATHER_DRUM:
  2175.     case DRUM_OF_EARTHQUAKE:
  2176.         res = do_play_instrument(obj);
  2177.         break;
  2178.     case HORN_OF_PLENTY:    /* not a musical instrument */
  2179.         if (obj->spe > 0) {
  2180.             struct obj *otmp;
  2181.             const char *what;
  2182.  
  2183.             obj->spe--;
  2184.             check_unpaid(obj);
  2185.             if (!rn2(13)) {
  2186.             otmp = mkobj(POTION_CLASS, FALSE);
  2187.             if (objects[otmp->otyp].oc_magic) do {
  2188.                 otmp->otyp = rnd_class(POT_BOOZE, POT_WATER);
  2189.             } while (otmp->otyp == POT_SICKNESS);
  2190.             what = "A potion";
  2191.             } else {
  2192.             otmp = mkobj(FOOD_CLASS, FALSE);
  2193.             if (otmp->otyp == FOOD_RATION && !rn2(7))
  2194.                 otmp->otyp = LUMP_OF_ROYAL_JELLY;
  2195.             what = "Some food";
  2196.             }
  2197.             pline("%s spills out.", what);
  2198.             otmp->blessed = obj->blessed;
  2199.             otmp->cursed = obj->cursed;
  2200.             otmp->owt = weight(otmp);
  2201.             otmp = hold_another_object(otmp,
  2202.                     (u.uswallow || Is_airlevel(&u.uz) ||
  2203.                      u.uinwater || Is_waterlevel(&u.uz)) ?
  2204.                            "Oops!  %s away from you!" :
  2205.                            "Oops!  %s to the floor!",
  2206.                            The(aobjnam(otmp, "slip")),
  2207.                            (const char *)0);
  2208.             makeknown(HORN_OF_PLENTY);
  2209.         } else
  2210.             pline(nothing_happens);
  2211.         break;
  2212.     default:
  2213.         pline("Sorry, I don't know how to use that.");
  2214.     xit:
  2215.         nomul(0);
  2216.         return 0;
  2217.     }
  2218.     nomul(0);
  2219.     return res;
  2220. }
  2221.  
  2222. #endif /* OVLB */
  2223.  
  2224. /*apply.c*/
  2225.